package es.unileon.rnag.jgen.operadores;

import java.util.*;

import es.unileon.rnag.jgen.Cromosoma;

/**
 * Clase que implementa el operador de selecci&oacute;n por ruleta
 * @author Abel Mayorga Gonz&aacute;lez
 * @author Sergio Fern&aacute;ndez Mart&iacute;nez
 * @version 1.0
 */
public class SeleccionRuleta extends Seleccion {

	/**
	 * Constructor
	 * @param porcentaje: Porcentaje de seleccionados en tanto por uno
	 */
	public SeleccionRuleta(float porcentaje){
		super(porcentaje);
	}
	
	@Override
	public List<Cromosoma> operar(int generacion, List<Cromosoma> poblacion) {
		//Numero de sujetos a seleccionar
		int nSujetos = (int)Math.floor(_porcentaje*poblacion.size());
		//Se obtiene la aptitud de cada cromosoma y la suma
		double[] aptitudes = new double[nSujetos];
		double suma = 0;
		for(int i = 0; i < nSujetos; i++){
			aptitudes[i] = poblacion.get(i).getAptitud();
			suma += aptitudes[i];
		}
		//Se asignan los rangos de seleccion a cada cromosoma
		aptitudes[0]/=suma;
		for(int i = 1; i < nSujetos; i++){
			aptitudes[i]/=suma;
			aptitudes[i]+=aptitudes[i-1];
		}
		List<Cromosoma> seleccionados = new ArrayList<Cromosoma>();
		for(int i = 0; i < nSujetos; i++){
			double aleatorio = Math.random();
			//Se obtiene el cromosoma en el que caiga el numero aleatorio
			if((aleatorio>=0)&&(aleatorio<aptitudes[0])){
				seleccionados.add(poblacion.get(0).clonar());
			} else {
				for(int j = 1; j < nSujetos; j++){
					if((aleatorio>=aptitudes[j-1])&&(aleatorio<aptitudes[j])){
						seleccionados.add(poblacion.get(j).clonar());
					}
				}
			}
		}
		return seleccionados;
	}

}
